

#include <QPainter>
#include <QStack>
#include "log.h"
#include "toolfill.h"
#include "imageeditor.h"

ToolFill::ToolFill(ImageEditor* parent) : EditorTool("fill", parent)
{
}

ToolFill::~ToolFill()
{
}

void ToolFill::mousePress(const QPoint& p)
{
	QStack<QPoint> stack;
	QPainter painter(image());
	painter.save();
	QPen mypen = QPen(pen().color());
	mypen.setWidth(1);
	painter.setPen(mypen);
	QColor newColor = pen().color();
	QColor oldColor = image()->pixel(p);
	
	if(newColor == oldColor)
		return;

	stack.push(p);
	while(!stack.isEmpty())
	{
		QPoint point = stack.pop();
		fillLine(&painter, point, stack, oldColor);
	}

	painter.restore();
}

void ToolFill::mouseRelease(const QPoint& p)
{
}

void ToolFill::mouseMove(const QPoint& p)
{
}

QRect ToolFill::boundingRect(const QPoint& p)
{
	return QRect(p.x() - pen().width() - 1, p.y() - pen().width() - 1, p.x() + pen().width() + 1, p.y() + pen().width() + 1);
}

QRect ToolFill::draw(QPainter* painter)
{
	return boundingRect(m_current);
}

void ToolFill::fillLine(QPainter* painter, const QPoint& p, QStack<QPoint>& stack, const QColor& oldColor)
{
	QRgb newColor = pen().color().rgb();
	QColor pointColor = image()->pixel(p);
	int x = p.x();
	bool upper = false;
	bool lower = false;
	while(pointColor == oldColor && x >= 0)
	{
		if((p.y() != 0) && (image()->pixel(x, p.y() - 1) == oldColor.rgb()))
		{
			if(!upper)
			{
				stack.push(QPoint(x, p.y() - 1));
				upper = true;
			}
		}
		else
			upper = false;

		if((p.y() != image()->height() - 1) && (image()->pixel(x, p.y() + 1) == oldColor.rgb()))
		{
			if(!lower)
			{
				stack.push(QPoint(x, p.y() + 1));
				lower = true;
			}
		}
		else
			lower = false;
		x--;
		pointColor = image()->pixel(x, p.y());
	}
	painter->drawLine(p.x(), p.y(), x + 1, p.y());
	x = p.x() + 1;
	pointColor = image()->pixel(x, p.y());
	upper = lower = false;
	while(pointColor == oldColor && x < image()->width())
	{
		if((p.y() != 0) && (image()->pixel(x, p.y() - 1) == oldColor.rgb()))
		{
			if(!upper)
			{
				stack.push(QPoint(x, p.y() - 1));
				upper = true;
			}
		}
		else
			upper = false;

		if((p.y() != image()->height() - 1) && (image()->pixel(x, p.y() + 1) == oldColor.rgb()))
		{
			if(!lower)
			{
				stack.push(QPoint(x, p.y() + 1));
				lower = true;
			}
		}
		else
			lower = false;
		x++;
		pointColor = image()->pixel(x, p.y());
	}
	painter->drawLine(p.x(), p.y(), x - 1, p.y());
}

